在以后互斥锁就简称是锁,除非遇到递归锁才叫回互斥锁
锁: 保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,使用锁后速度会变慢,但牺牲了速度却保证了数据安全。
锁其实就是将异步执行变成了同步执行
from multiprocessing import Lock
lock = Lock() # 获取锁
lock.acquire() # 上锁
print(123)
lock.release() # 解锁
1. 没有使用锁的抢票例子
- 如果没有上锁,多个进程修改一个数据的时候,产生数据混乱,
- 所有人都可以买到票,且剩下的票数也会有问题,因为所有进程几乎在同时读取文件,且读取到的票数都是大于0的,所以所有进程都可以抢到票,且每个进程将读取到的票数减1后再重新写入文件中,后写入的票数就会覆盖前面所写入的票数,这样就会造成数据的混乱或不安全
# 没有上锁的抢票例子
import json
import time
import random
from multiprocessing import Lock
from multiprocessing import Process
# 查看还有多少票
def search(i):
with open('ticket', encoding='utf-8') as f:
ticket_num = json.load(f)['count']
print(i, ticket_num)
# 抢票
def get(i):
with open('ticket', encoding='utf-8') as f:
ticket_num = json.load(f)['count'] # 获取现有的票数
time.sleep(random.random()) # 模拟网路延时
if ticket_num > 0:
with open('ticket', 'w', encoding='utf-8') as f:
json.dump({'count': ticket_num - 1}, f)
print('%s,买到票了' % i)
else:
print('%s,没票了' % i)
def task(i):
search(i)
get(i)
if __name__ == '__main__':
for i in range(5):
p = Process(target=task, args=(i,))
p.start()
# ticket.txt -> 执行前
{"count": 10}
# ticket.txt -> 执行后
{"count": 2}
2. 使用锁的抢票例子
- 每一次只允许一个进程对票数进行查看修改,这样就不会出现上面的情况
# 上锁后的抢票例子
import json
import time
import random
from multiprocessing import Lock
from multiprocessing import Process
# 查看还有多少票
def search(i):
with open('ticket', encoding='utf-8') as f:
ticket_num = json.load(f)['count']
print(i, ticket_num)
# 抢票
def get(i):
with open('ticket', encoding='utf-8') as f:
ticket_num = json.load(f)['count'] # 获取现有的票数
time.sleep(random.random()) # 模拟网路延时
if ticket_num > 0:
with open('ticket', 'w', encoding='utf-8') as f:
json.dump({'count': ticket_num - 1}, f)
print('%s,买到票了' % i)
else:
print('%s,没票了' % i)
def task(i, lock):
search(i)
lock.acquire() # 上锁,每次只允许一个进程进入,且上锁后就不允许其他进程进入执行 lock.acquire() 下方的代码
get(i) # 执行抢票
lock.release() # 解锁,解锁后下一个进程才允许被进入执行 lock.acquire() 下方的代码
if __name__ == '__main__':
lock = Lock() # 获取锁
for i in range(10):
p = Process(target=task, args=(i, lock))
p.start()
# ticket.txt -> 执行前
{"count": 1}
# ticket.txt -> 执行后
{"count": 0}